<template>
  <div
    class="c-scroll-container"
    :style="{ width: width + 'px', height: height + 'px' }"
  >
    <div
      class="c-scroll-list"
      ref="scrollListContainer"
      @mouseenter="pauseAnimation"
      @mouseleave="resumeAnimation"
      :class="{
        'scroll-up': props.direction === 'up',
        'scroll-down': props.direction === 'down',
        'scroll-left': props.direction === 'left',
        'scroll-right': props.direction === 'right',
        'flex-col': getDirection() == 0,
        'flex-row': getDirection() == 1,
        paused: isPaused,
      }"
      :style="{ animationDuration: animationDuration + 'ms' }"
    >
      <div
        v-for="i in 2"
        ref="listRef"
        class="flex"
        :class="{
          'flex-col': getDirection() == 0,
          'flex-row': getDirection() == 1,
        }"
      >
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, nextTick } from "vue";

const props = defineProps({
  direction: {
    default: "up",
    type: String,
  },
  width: {
    default: 500,
    type: Number,
  },
  height: {
    default: 300,
    type: Number,
  },
  stepTime: {
    default: 20,
    type: Number,
  },
  openHover: {
    type: Boolean,
    default: true,
  },
});

const scrollListContainer = ref(null); // 用于绑定 DOM 元素
const animationDuration = ref("10000"); // 默认动画时长（10秒）
const listRef = ref();

// 暂停动画
const isPaused = ref(false);
const pauseAnimation = () => {
  if (!props.openHover) return;
  isPaused.value = true;
};

// 继续动画
const resumeAnimation = () => {
  if (!props.openHover) return;
  isPaused.value = false;
};

const getDirection = () => {
  // 0 垂直方向 1水平方向
  let res = props.direction == "up" || props.direction == "down" ? 0 : 1;
  return res;
};

let width = ref(props.width);
let height = ref(props.height);
let scrollDistance = ref();

/* 1、出现闪动，空白 主要是视口宽高 和内容宽高不匹配出现的问题 */
/* 2、 因为计算的是元素真实高度 不要给slot 遍历的元素加margin 也容易出现宽高不对的问题，<div><div class="item"></div></div> 在外边套一层 给item 如果需要margin的效果 利用padding 加在外层div */
/* 3、所有的内容没滚动完就又从头开始滚动都是因为滚动的列表宽度或者高度不正确，审查 listRef【0】的宽度 高度 就会发现问题所在*/

onMounted(() => {
  nextTick(() => {
    if (scrollListContainer.value) {
      if (getDirection() == 0) {
        scrollDistance.value = listRef.value[0].clientHeight;
        //上下滚动设置可视区高度（为了避免可视区高度比内容高度高 ，滚动一轮结束出现空白 ）
        if (listRef.value[0].clientHeight < props.height) {
          height.value = listRef.value[0].clientHeight;
        }
      } else {
        scrollDistance.value = listRef.value[0].clientWidth;
        // 左右滚动设置可视区宽度（为了避免可视区宽度比内容宽度高 ，滚动一轮结束出现空白 ）
        if (listRef.value[0].clientWidth < props.width) {
          width.value = listRef.value[0].clientWidth;
        }
      }

      // 持续时间  = 滚动距离 * 每像素滚动时间（ms）
      const duration = scrollDistance.value * props.stepTime;
      animationDuration.value = duration.toString();
      console.log(duration, "持续时间", scrollDistance.value, "滚动距离");
    } else {
      console.error("scrollListContainer is not available");
    }
  });
});
</script>

<style scoped>
.c-scroll-container {
  overflow: hidden;
  position: relative;
}

.c-scroll-list {
  width: fit-content;
  display: flex;
  /* flex-direction: column; */
}

/* 定义滚动动画 */
.scroll-up {
  animation: scrollTop linear infinite normal;
}

.scroll-down {
  animation: scrollBottom linear infinite normal;
}
.scroll-left {
  animation: scrollLeft linear infinite normal;
}
.scroll-right {
  animation: scrollRight linear infinite normal;
}

.paused {
  animation-play-state: paused !important;
}

@keyframes scrollTop {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(0, -50%, 0);
  }
}

@keyframes scrollBottom {
  0% {
    transform: translate3d(0, -50%, 0);
  }

  100% {
    transform: translate3d(0, 0%, 0);
  }
}
@keyframes scrollRight {
  0% {
    transform: translate3d(-50%, 0, 0);
  }

  100% {
    transform: translate3d(0, 0%, 0);
  }
}
@keyframes scrollLeft {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(-50%, 0%, 0);
  }
}
</style>
<!-- 

通过props 传入方向 设置不同的动画 名
  @keyframes scrollLeft {
  0% {
    transform: translate3d(0, 0, 0);
  }

  100% {
    transform: translate3d(-50%, 0%, 0);
  }
}

scrollLeft 是动画名，在动画起始时 元素xyz方向不移动，动画结束时x方向向负方向也就是向左移动其元素的50% 
因为为了实现无缝衔接的效果我们 v-for i in 2 渲染了两个一样的div ，也就是一个div出了视口 运动了元素的50% 
可以在审查将鼠标放到第一个div上看循环效果，就会发现这个div出了视口立马跳回到了一开始的状态

配合 .scroll-left {
  animation: scrollLeft linear infinite normal;
}中的infinite 实现无限循环

动画时长是根据内容的滚动距离和每像素滚动时间动态计算的。
这确保了无论内容的实际尺寸如何，动画都能在适当的时间内完成，从而保持流畅的滚动效果。

-->
